package org.ifilm.dao;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.ifilm.model.City;
import org.ifilm.model.Country;
import org.ifilm.model.Language;
import org.ifilm.model.TipsAndTricks;
import org.ifilm.model.UserType;

/**
 * 
 * @author Mustafa Genç
 *
 */
@Repository
public class UtilDaoImpl implements UtilDao {

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	public List<Country> listCountries() {
		try {
			Query query = entityManager.createQuery(listAllCountriesQuery());

			return (List<Country>) query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private String listAllCountriesQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select c from country c");
		return strBuild.toString();
	}

	@Override
	public List<City> getCitiesByCountry(Long countryId) {
		try {
			Query query = entityManager.createQuery(getCitiesByCountryQuery());
			
			query.setParameter("id", countryId);
			
			return (List<City>) query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	private String getCitiesByCountryQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select c from city c where c.country.id=:id");
		return strBuild.toString();
	}

	@Override
	public List<Language> getLanguages() {
		try {
			Query query = entityManager.createQuery(getLanguagesQuery());

			return (List<Language>) query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	private String getLanguagesQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select l from language l");
		return strBuild.toString();
	}

	@Override
	public List<Object> getSearchable(Integer page, Integer max, String searchText) {
		try {
			Query query = entityManager.createQuery(getProjectQuery());
			
			query.setParameter("searchText", "%" + searchText + "%");
			query.setFirstResult((page - 1) * max);
			query.setMaxResults(max);
			
			List<Object> objects = new ArrayList<Object>();
			List<Object> projectObjects = (List<Object>) query.getResultList();
			
			if (projectObjects != null) {
				objects.addAll(projectObjects);
			}
			
			if (objects.size() < max) {
				query = entityManager.createQuery(getUserQuery());
				
				query.setParameter("searchText", "%" + searchText + "%");
				query.setFirstResult((page - 1) * max);
				query.setMaxResults(max - objects.size());
				
				List<Object> userObjects = (List<Object>) query.getResultList();
				
				if (userObjects != null) {
					objects.addAll(userObjects);
				}
			}
			
			return objects;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	private String getProjectQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select p from project p where p.projectName like :searchText");
		return strBuild.toString();
	}
	
	private String getUserQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select u from user u where (u.name like :searchText or u.surname like :searchText)");
		return strBuild.toString();
	}
	
	@Override
	public List<UserType> getUserTypes() {
		try {
			Query query = entityManager.createQuery(getUserTypesQuery());

			return (List<UserType>) query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	private String getUserTypesQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select t from usertype t");
		return strBuild.toString();
	}
	
	@Override
	public TipsAndTricks createTipAndTrick(TipsAndTricks tipAndTrick) {
		return entityManager.merge(tipAndTrick);		
	}

	@Override
	public List<TipsAndTricks> getTipsByUser(Long userId) {
		try {
			Query query = entityManager.createQuery(getTipsByUserQuery());
			query.setParameter("userId", userId);	
			return (List<TipsAndTricks>)query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	@Override
	public List<TipsAndTricks> getAllTips() {
		try {
			Query query = entityManager.createQuery(getAllTipsQuery());
			return (List<TipsAndTricks>)query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public List<TipsAndTricks> getTipsByType(int type) {
		try {
			Query query = entityManager.createQuery(getTipsByUserQuery());
			query.setParameter("paramType", type);
			return (List<TipsAndTricks>)query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public List<TipsAndTricks> getTipsBySubject(String subject) {
		try {
			Query query = entityManager.createQuery(getTipsBySubjectQuery());
			query.setParameter("subject", subject);
			return (List<TipsAndTricks>)query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}	
	
	private String getTipsByUserQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select tt from tips_and_tricks tt  where tt.creator =:userId order by tt.creator ASC");
		return strBuild.toString();
	}
	
	private String getTipsBySubjectQuery(){
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select tt from tips_and_tricks tt where tt.subject=:subject order by tt.creator ASC");
		return strBuild.toString();
	}
	
	public String getAllTipsQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select tt from tips_and_tricks tt");
		return strBuild.toString();
	}
}